home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / FOLLOW.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  7KB  |  260 lines

  1. #include "pt.h"
  2. #include "conio.h"
  3.  
  4. /* return 1 only if you see both buttons simultaneously down */
  5. int pascal
  6. /* XTAG:followSelection */
  7. followSelection(w, lastRow, lastCol, evHead, oneTime)
  8.     struct window *w;
  9.     int lastRow, lastCol, evHead, oneTime;
  10. {
  11.     extern unsigned char msgBuffer[];
  12.     extern long selBegin, selEnd;
  13.     extern int selMode;
  14.     extern union REGS rin, rout;
  15.     extern int scrRows, scrCols;
  16.     extern struct event events[];
  17.     extern unsigned char scrMapReset;
  18.     extern int mousePresent;
  19.     extern int autoScrollRate;
  20.     extern int debug;
  21.     extern int videoMode;
  22.  
  23.     int col1, col2, l, m, n, r, fileId, ret;
  24.     int oldRow1, oldRow2, newRow1, newRow2;
  25.     int selRow1, selRow2, redoRow1, redoRow2;
  26.     int anchRow1, anchRow2, curRow, curCol;
  27.     int startButtons;
  28.     long cpNew, cpNew1, cpNew2, cp1;
  29.     long anchBegin, anchEnd, oldCp1, anchCp1;
  30.     long selCp1;
  31.  
  32.     /* get the present mouse button state */
  33.     if( mousePresent ) {
  34.         rin.x.ax = 3;
  35.         int86(51, &rin, &rout);
  36.         startButtons = rout.x.bx;
  37.     } else
  38.         startButtons = 0x7;
  39.  
  40.     /* anchor the selection at the current selection */
  41.     anchBegin = selBegin;
  42.     anchEnd = selEnd;
  43.     fileId = w->fileId;
  44.     col1 = w->col1 + 1;
  45.     col2 = w->col2 - 1;
  46.     ret = 0;
  47.  
  48. restartFollowing:
  49.     /* what rows is the selection on now? */
  50.     if( selBegin <= w->posTopline ) {
  51.         anchCp1 = w->posTopline;
  52.         anchRow1 = w->row1 + 1;
  53.     } else {
  54.         n = -1;
  55.         anchCp1 = prevLine(fileId, selBegin, &n);
  56.         posToxy(w, selBegin, &anchRow1, &r);
  57.     }
  58.     oldRow1 = anchRow1;
  59.     oldCp1 = anchCp1;
  60.  
  61.     posToxy(w, selEnd, &anchRow2, &r);
  62.     oldRow2 = anchRow2;
  63.     if( oneTime ) {
  64.         curRow = lastRow;
  65.         curCol = lastCol;
  66.         goto firstTime;
  67.     }
  68.  
  69.     /* This is the loop that follows the cursor selection */
  70.     while( 1 ) {
  71.         /* first find out the current cursor position and */
  72.         /* see if it has moved since we last checked */
  73.         /* wait for a mouse event */
  74.         while( !isMouseEvent(0) ) {
  75.             /* This is a BIOS call that does not have any */
  76.             /* direct purpose.  It seems to be necessary so */
  77.             /* that things will not freeze up after a Ctrl-C */
  78.             /* is handled.  I'm not sure why. */
  79.             getCPos(&l, &m);
  80.         }
  81.         evHead = getMouseEvent();
  82.         /* skip intermediate mouse movements if other mouse events */
  83.         /* are already on the queue */
  84.         while( 1 ) {
  85.             if( events[evHead].mask != 0x1 )
  86.                 break;
  87.             if( !isMouseEvent(0) )
  88.                 break;
  89.             evHead = getMouseEvent();
  90.         }
  91.         curRow = events[evHead].vertical>>3;
  92.         curCol = events[evHead].horizontal>>3;
  93.  
  94.         /* normalize extension outside the window */
  95.         if( curRow <= w->row1 ) {
  96.             curRow = w->row1 + 1;
  97.             while( 1 ) {
  98.                 /* set up the screen map and scroll window */
  99.                 scrMapReset = 0;
  100.                 setMap(w->row1, w->col1, w->row2, w->col2,
  101.                     1, w->textColor);
  102.                 maskTop(w);
  103.                 downScroll(w, autoScrollRate);
  104.                 /* change the selection */
  105.                 l = w->row1 + 1;
  106.                 m = w->col1 + 1;
  107.                 xyToPos(&l, &m, &n, &cp1,
  108.                     (struct window **)&r);
  109.                 if( selBegin > cp1 )
  110.                     selBegin = cp1;
  111.                 redrawBox(0, 0, scrRows-1, scrCols-1);
  112.                 scrMapReset = 1;
  113.                 setMap(w->row1, w->col1, w->row2, w->col2,
  114.                     1, w->textColor);
  115.                 oldRow1 = w->row1 + 1;
  116.                 oldCp1  = w->posTopline;
  117.                 oldRow2 = w->row2 - 1;
  118.                 if( isMouseEvent(0) ) {
  119.                     evHead = getMouseEvent();
  120.                     goto restartFollowing;
  121.                 }
  122.             }
  123.         } else if( curRow >= w->row2 ) {
  124.             curRow = w->row2 - 1;
  125.             while( 1 ) {
  126.                 /* set up the screen map and scroll window */
  127.                 scrMapReset = 0;
  128.                 setMap(w->row1, w->col1, w->row2, w->col2,
  129.                     1, w->textColor);
  130.                 maskTop(w);
  131.                 upScroll(w, autoScrollRate);
  132.                 /* change the selection */
  133.                 l = w->row2 - 1;
  134.                 m = w->col2 - 1;
  135.                 xyToPos(&l, &m, &n, &cp1,
  136.                     (struct window **)&r);
  137.                 if( selEnd < cp1 )
  138.                     selEnd = cp1;
  139.                 redrawBox(0, 0, scrRows-1, scrCols-1);
  140.                 scrMapReset = 1;
  141.                 setMap(w->row1, w->col1, w->row2, w->col2,
  142.                     1, w->textColor);
  143.                 oldRow1 = w->row1 + 1;
  144.                 oldCp1  = w->posTopline;
  145.                 oldRow2 = w->row2 - 1;
  146.                 if( isMouseEvent(0) ) {
  147.                     evHead = getMouseEvent();
  148.                     goto restartFollowing;
  149.                 }
  150.             }
  151.         } else if( curCol <= w->col1 ) {
  152.             curCol = w->col1 + 1;
  153.         } else if( curCol >= w->col2 ) {
  154.             curCol = w->col2 - 1;
  155.         }
  156.  
  157.         if( curRow != lastRow || curCol != lastCol ) {
  158. firstTime:
  159.             /* The cursor has moved, so update the selection */
  160.             /* get the file position of the cursor position */
  161.             cpNew = xyToWindow(w, &curRow, &curCol);
  162.  
  163.             /* Extend it according the the selection mode */
  164.             modeExtend(w, cpNew, &cpNew1, &cpNew2);
  165.  
  166.             if( cpNew1 < anchBegin ) {
  167.                 selBegin = cpNew1;
  168.                 newRow1 = curRow;
  169.                 n = -1;
  170.                 cp1 = prevLine(fileId, cpNew1, &n);
  171.             } else {
  172.                 selBegin = anchBegin;
  173.                 newRow1 = anchRow1;
  174.                 cp1 = anchCp1;
  175.             }
  176.             if( cpNew2 > anchEnd ) {
  177.                 selEnd = cpNew2;
  178.                 newRow2 = curRow;
  179.             } else {
  180.                 selEnd = anchEnd;
  181.                 newRow2 = anchRow2;
  182.             }
  183.  
  184.             /* remember the rows of the current selection */
  185.             selRow1 = newRow1;
  186.             selCp1 = cp1;
  187.             selRow2 = newRow2;
  188.  
  189.             /* what rows do we need to redraw? */
  190.             /* we need to erase the old selection as well as */
  191.             /* draw the new selection */
  192.             if( oldRow1 < newRow1 ) {
  193.                 newRow1 = oldRow1;
  194.                 cp1 = oldCp1;
  195.             } else
  196.                 oldCp1 = cp1;
  197.             if( oldRow2 > newRow2 )
  198.                 newRow2 = oldRow2;
  199.  
  200.             /* try to reduce the screen redrawing by figuring */
  201.             /* out which rows have actually changed */
  202.             /* do not optimize for movement above the anchor row */
  203.             if( selRow1 == oldRow1 && selRow1 >= anchRow1) {
  204.                 if( selRow2 >= oldRow2 ) {
  205.                     redoRow1 = oldRow2;
  206.                     redoRow2 = selRow2;
  207.                 } else {
  208.                     redoRow1 = selRow2;
  209.                     redoRow2 = oldRow2;
  210.                 }
  211.             } else {
  212.                 redoRow1 = newRow1;
  213.                 redoRow2 = newRow2;
  214.             }
  215.  
  216.             /* update the changed rows in the screen buffer */
  217.             for(r = newRow1; r <= redoRow2; r++) {
  218.                 if( redoRow1 <= r ) {
  219.                     cp1 = fillLine(w, cp1, r, col1, col2);
  220.                 } else {
  221.                     n = 1;
  222.                     cp1 = nextLine(fileId, cp1, &n);
  223.                 }
  224.                 if( cp1 == -1 )    /* EOF? */
  225.                     break;
  226.             }
  227.             if( oneTime ) {
  228.                 oneTime = 0;
  229.                 updateScreen(0, scrRows-1);
  230.             } else {
  231.                 updateScreen(redoRow1, redoRow2);
  232.             }
  233.  
  234.             /* remember some things for the next iteration */
  235.             oldRow1 = selRow1;
  236.             oldCp1 = selCp1;
  237.             oldRow2 = selRow2;
  238.             lastRow = curRow;
  239.             lastCol = curCol;
  240.         }
  241.  
  242.         /* are the buttons up now? */
  243.         if( events[evHead].buttons == 0 )
  244.             break;
  245.  
  246.         /* check for both buttons down */
  247.         if( ((~startButtons) & events[evHead].buttons) != 0 ) {
  248.             ret = 1;
  249.             break;
  250.         }
  251.     }
  252.  
  253.     /* selecting the end of line should include both CR and LF */
  254.     if( readChar(fileId, selBegin) == '\n' ) {
  255.         if( readChar(fileId, --selBegin) != '\r' )
  256.             ++selBegin;
  257.     }
  258.     return ret;
  259. }
  260.